package com.md.config.database;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Component;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author 刘骄阳
 * 2022-04-06 18:43
 * 应用sharding分表时，LocalDateTime无法解析
 * sharding基于jdk1.7，缺少rs.getObject方法
 * 未来升级版本应该能解决这个问题
 */
@Component
//定义转换器支持的JAVA类型
@MappedTypes(LocalDateTime.class)
//定义转换器支持的数据库类型
@MappedJdbcTypes(value = JdbcType.DATE, includeNullJdbcType = true)
@ConditionalOnClass(value = {MybatisPlusInterceptor.class})
public class CustomLocalDateTypeHandler extends BaseTypeHandler<LocalDateTime> {
  private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

  @Override
  public void setNonNullParameter(final PreparedStatement ps, final int i,
                                  final LocalDateTime parameter, final JdbcType jdbcType)
    throws SQLException {
    if (parameter != null) {
      ps.setString(i, dateTimeFormatter.format(parameter));
    }
  }

  @Override
  public LocalDateTime getNullableResult(final ResultSet rs, final String columnName) throws SQLException {
    String target = rs.getString(columnName);
    if (StringUtils.isEmpty(target)) {
      return null;
    }
    return LocalDateTime.parse(target, dateTimeFormatter);
  }

  @Override
  public LocalDateTime getNullableResult(final ResultSet rs, final int columnIndex) throws SQLException {
    String target = rs.getString(columnIndex);
    if (StringUtils.isEmpty(target)) {
      return null;
    }
    return LocalDateTime.parse(target, dateTimeFormatter);
  }

  @Override
  public LocalDateTime getNullableResult(final CallableStatement cs, final int columnIndex) throws SQLException {
    String target = cs.getString(columnIndex);
    if (StringUtils.isEmpty(target)) {
      return null;
    }
    return LocalDateTime.parse(target, dateTimeFormatter);
  }
}
